Skip to main content

brain.id86.net 404 Recovery (Cloudflare Access Wrong Origin)

This guide documents the maintenance steps used to restore brain.id86.net when the site was reachable through Cloudflare Access but returned a 404 the requested path could not be found error after login.

Environment Context

  • Stack: Docusaurus in Docker, Cloudflare Tunnel (cloudflared), Cloudflare Zero Trust / Access.
  • Hostname: brain.id86.net.
  • Tunnel config: /opt/docker-data/tunnel/config/config.yml.
  • Active site container: docusaurus-brain2.

Symptom Pattern

  • Public request to https://brain.id86.net redirected correctly to Cloudflare Access login.
  • After Access, the site showed 404 the requested path could not be found.
  • This confirmed the hostname and Access app were live, but the origin route behind the tunnel was wrong.

Root Cause Confirmed

The tunnel ingress for brain.id86.net pointed to the wrong Docusaurus container:

- hostname: brain.id86.net
service: http://docusaurus:3000

That origin returned 404 on /, while the correct production content for the public hostname brain.id86.net was being served by the docusaurus-brain2 container.

Verified behavior during incident:

sudo docker run --rm --network app-network curlimages/curl:8.12.1 -I -sS http://docusaurus:3000/
sudo docker run --rm --network app-network curlimages/curl:8.12.1 -I -sS http://docusaurus-brain2:3000/

Observed result:

  • http://docusaurus:3000/ -> 404 Not Found
  • http://docusaurus-brain2:3000/ -> 200 OK

Fix Applied

Updated tunnel config:

  • File: /opt/docker-data/tunnel/config/config.yml
  • Public hostname remains: brain.id86.net
  • Correct backend origin service: http://docusaurus-brain2:3000

Change:

- hostname: brain.id86.net
service: http://docusaurus-brain2:3000

Reloaded tunnel:

sudo docker restart cloudflared

Validation Steps

1) Confirm Cloudflare Access still protects the site

curl -I https://brain.id86.net/

Expected result:

  • 302 redirect to the Cloudflare Access login page.

2) Confirm the correct origin responds inside Docker network

sudo docker run --rm --network app-network curlimages/curl:8.12.1 -I -sS http://docusaurus-brain2:3000/

Expected result:

  • 200 OK

3) Confirm tunnel comes back cleanly

sudo docker logs --tail 50 cloudflared

Expected result:

  • tunnel connections register successfully after restart
  • no fresh 404 issue for brain.id86.net caused by wrong origin mapping

Maintenance Checklist For Similar Cases

When a Cloudflare-protected site shows 404 after login:

  1. Check whether the hostname itself is live:
curl -I https://brain.id86.net/
  1. Inspect running containers:
sudo docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
  1. Review the tunnel config:
sudo sed -n '1,120p' /opt/docker-data/tunnel/config/config.yml
  1. Test each possible origin from the Docker network:
sudo docker run --rm --network app-network curlimages/curl:8.12.1 -I -sS http://docusaurus:3000/
sudo docker run --rm --network app-network curlimages/curl:8.12.1 -I -sS http://docusaurus-brain2:3000/
  1. Point the hostname to the origin that returns the expected status.
  2. Restart cloudflared.
  3. Re-test the public hostname and the origin.

Why This Happened

In this environment there are two Docusaurus containers:

  • docusaurus
  • docusaurus-brain2

Because both resolve on app-network, Cloudflare Tunnel could reach either one if configured, but only docusaurus-brain2 was serving the intended site root successfully for brain.id86.net. The hostname was therefore healthy at the Access layer but misrouted at the origin layer.

  1. Keep a short hostname-to-container inventory for all tunnel routes.
  2. Verify each ingress target with an internal curl check before restarting cloudflared.
  3. Remove unused legacy origins from active tunnel mappings where possible.
  4. Review cloudflared logs separately for unrelated services so they do not distract from the active incident.

Final Mapping After Recovery

  • Public route: brain.id86.net
  • Backend origin used by the tunnel: http://docusaurus-brain2:3000